/***************************************************************************
 *                                                                         *
 *                              AsynChord.java                             *
 *                            -------------------                          *
 *   date                 : 15.10.2005                                     *
 *   copyright            : (C) 2004-2008 Distributed and                  *
 *                              Mobile Systems Group                       *
 *                              Lehrstuhl fuer Praktische Informatik       *
 *                              Universitaet Bamberg                       *
 *                              http://www.uni-bamberg.de/pi/              *
 *   email                : sven.kaffille@uni-bamberg.de                   *
 *                          karsten.loesing@uni-bamberg.de                 *
 *                                                                         *
 *                                                                         *
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   A copy of the license can be found in the license.txt file supplied   *
 *   with this software or at: http://www.gnu.org/copyleft/gpl.html        *
 *                                                                         *
 ***************************************************************************/
package de.uniba.wiai.lspi.chord.service;

import java.io.Serializable;

import de.uniba.wiai.lspi.chord.data.ID;
import de.uniba.wiai.lspi.chord.data.URL;

/**
 * <p>
 * Interface to Chord distributed hash table for asynchronous method
 * invocations.
 * </p>
 * <p>
 * The methods
 * <ul>
 * <li>{@link #insert(Key, Serializable, ChordCallback)}</li>
 * <li>{@link #remove(Key, Serializable, ChordCallback)}</li>
 * <li>{@link #retrieve(Key, ChordCallback)}</li>
 * </ul>
 * perform the requested operation (insert, remove, or retrieve) and delegate
 * the invocation result to the provided {@link ChordCallback callback} object.
 * </p>
 * <p>
 * The methods
 * <ul>
 * <li>{@link #insertAsync(Key, Serializable)}</li>
 * <li>{@link #removeAsync(Key, Serializable)}</li>
 * <li>{@link #retrieveAsync(Key)}</li>
 * </ul>
 * perform the requested operation (insert, remove, or retrieve) and the result
 * can be obtained or the completion of the method can be detected with help of
 * the returned instance of {@link ChordFuture}.
 * </p>
 * 
 * @author sven
 * @version 1.0.5
 */
public interface AsynChord {

	/**
	 * Returns the {@link URL} of the local node; is <code>null</code> if no network has been
	 * created or joined.
	 * 
	 * @return {@link URL} of local node.
	 */
	public abstract URL getURL();

	/**
	 * Sets the {@link URL} of the local node to the given value; only available
	 * before creating or joining a network.
	 * 
	 * @param nodeURL
	 *            New {@link URL} of local node.
	 * @throws NullPointerException
	 *             If given URL reference has value <code>null</code>.
	 * @throws IllegalStateException
	 *             If network has already been created or joined.
	 */
	public abstract void setURL(URL nodeURL) throws IllegalStateException;

	/**
	 * Returns the {@link ID} of the local node; is <code>null</code> if no network has been
	 * created or joined.
	 * 
	 * @return {@link ID} of local node.
	 */
	public abstract ID getID();

	/**
	 * Sets the {@link ID} of the local node to the given value; only available
	 * before creating or joining a network.
	 * 
	 * @param nodeID
	 *            New {@link ID} of local node.
	 * @throws NullPointerException
	 *             If given ID reference has value <code>null</code>.
	 * @throws IllegalStateException
	 *             If network has already been created or joined.
	 */
	public abstract void setID(ID nodeID) throws IllegalStateException;

	/**
	 * Creates a new chord network which is not connected to any other node.
	 * Assumes that at least the node URL has been set before by {@link #setURL}.
	 * If no ID has been set before, it is generated by applying a hash function
	 * on the node URL.
	 * 
	 * @throws ServiceException
	 *             Is thrown if creating the local chord node fails, e.g. due to
	 *             unability of creating the endpoint for incoming messages. Is
	 *             also thrown if no URL has been set before.
	 */
	public abstract void create() throws ServiceException;

	/**
	 * Creates a new chord network which is not connected to any other node. The
	 * node ID is generated by applying a hash function on the node {@link URL}.
	 * 
	 * @param localURL
	 *            {@link URL} on which this node accepts incoming requests from
	 *            other chord nodes. The {@link ID} of this node is generated by
	 *            applying a hash function on the node {@link URL}.
	 * @throws NullPointerException
	 *             If <code>localURL</code> is <code>null</code>.
	 * @throws ServiceException
	 *             Is thrown if creating the local chord node fails, e.g. due to
	 *             unability of creating the endpoint for incoming messages.
	 */
	public abstract void create(URL localURL) throws ServiceException;

	/**
	 * Creates a new chord network which is not connected to any other node.
	 * 
	 * @param localURL
	 *            {@link URL} on which this node accepts incoming requests from
	 *            other chord nodes.
	 * @param localID
	 *            {@link ID} of this node.
	 * @throws NullPointerException
	 *             If <code>localURL</code> or <code>localID</code> is
	 *             <code>null</code>.
	 * @throws ServiceException
	 *             Is thrown if creating the local chord node fails, e.g. due to
	 *             unability of creating the endpoint for incoming messages.
	 */
	public abstract void create(URL localURL, ID localID)
			throws ServiceException;

	/**
	 * Joins an existing chord network and announces its presence to the other
	 * nodes. Assumes that at least the node {@link URL} has been set before by
	 * {@link #setURL}. If no {@link ID} has been set before, it is generated
	 * by applying a hash function on the node {@link URL}.
	 * 
	 * @param bootstrapURL
	 *            {@link URL} of one existing node which is used as bootstrap
	 *            node.
	 * @throws NullPointerException
	 *             If <code>bootstrapURL</code> is <code>null</code>.
	 * @throws ServiceException
	 *             If joining fails this exception is thrown. This may be due to
	 *             failure of establishing an endpoint or communication problems
	 *             when contacting the bootstrap node. Is also thrown if no URL
	 *             has been set before.
	 */
	public abstract void join(URL bootstrapURL) throws ServiceException;

	/**
	 * Joins an existing chord network and announces its presence to the other
	 * nodes. The node {@link ID} is generated by applying a hash function on
	 * the node {@link URL}.
	 * 
	 * @param localURL
	 *            The local node is made available under this {@link URL}.
	 * @param bootstrapURL
	 *            {@link URL} of one existing node which is used as bootstrap
	 *            node.
	 * @throws NullPointerException
	 *             If <code>localURL</code> or <code>bootstrapURL</code> is
	 *             <code>null</code>.
	 * @throws ServiceException
	 *             If joining fails this exception is thrown. This may be due to
	 *             failure of establishing an endpoint or communication problems
	 *             when contacting the bootstrap node.
	 */
	public abstract void join(URL localURL, URL bootstrapURL)
			throws ServiceException;

	/**
	 * Joins an existing chord network and announces its presence to the other
	 * nodes.
	 * 
	 * @param localURL
	 *            The local node is made available under this {@link URL}.
	 * @param localID
	 *            {@link ID} of this node.
	 * @param bootstrapURL
	 *            {@link URL} of one existing node which is used as bootstrap
	 *            node.
	 * @throws NullPointerException
	 *             If <code>localURL</code>, <code>localID</code>, or
	 *             <code>bootstrapURL</code> is <code>null</code>.
	 * @throws ServiceException
	 *             If joining fails this exception is thrown. This may be due to
	 *             failure of establishing an endpoint or communication problems
	 *             when contacting the bootstrap node.
	 */
	public abstract void join(URL localURL, ID localID, URL bootstrapURL)
			throws ServiceException;

	/**
	 * Disconnects from the network.
	 * 
	 * @throws ServiceException
	 *             If properly leaving the network fails this exception is
	 *             thrown. The network might have been left as if the local node
	 *             has failed. However, disconnecting from the network is done
	 *             in every case.
	 */
	public abstract void leave() throws ServiceException;
	
	/**
	 * Asynchronous method to retrieve the entries associated with
	 * <code>key</code>. Implementations of this method must return
	 * immediately and the result of the retrieval must be passed to the
	 * provided <code>callback</code> instance.
	 * 
	 * @param key
	 *            The key for which the associated entries should be retrieved.
	 * 
	 * @param callback
	 *            The {@link ChordCallback} to which to pass the retrieval
	 *            result.
	 */
	public void retrieve(Key key, ChordCallback callback);

	/**
	 * Asynchronous method to insert <code>entry</code> under the provided
	 * <code>key</code>. Implementations of this method must return
	 * immediately and the completion of the insertion must be reported to the
	 * provided <code>callback</code> instance.
	 * 
	 * @param key
	 *            The {@link Key} to associate with <code>entry</code>
	 * @param entry
	 *            The entry to insert.
	 * @param callback
	 *            The {@link ChordCallback} to which to pass the retrieval
	 *            result.
	 */
	public void insert(Key key, Serializable entry, ChordCallback callback);

	/**
	 * Asynchronous method to remove <code>entry</code> under the provided
	 * <code>key</code>. Implementations of this method must return
	 * immediately and the completion of the removal must be reported to the
	 * provided <code>callback</code> instance.
	 * 
	 * @param key
	 *            The {@link Key} associated with <code>entry</code>
	 * @param entry
	 *            The entry to insert.
	 * @param callback
	 *            The {@link ChordCallback} to which to pass the retrieval
	 *            result.
	 */
	public void remove(Key key, Serializable entry, ChordCallback callback);

	/**
	 * Asynchronous method to retrieve the entries associated with
	 * <code>key</code>. Implementations of this method must return
	 * immediately and return an implementation of {@link ChordRetrievalFuture},
	 * which can be used later on to retrieve the retrieved results.
	 * 
	 * @param key
	 *            The {@link Key} for that the associated entries should be
	 *            retrieved.
	 * @return {@link ChordRetrievalFuture} that represents the result of the
	 *         retrieve method.
	 */
	public ChordRetrievalFuture retrieveAsync(Key key);

	/**
	 * Asynchronous method to insert <code>entry</code> with <code>key</code>.
	 * Implementations of this method must return immediately and return an
	 * implementation of {@link ChordFuture}, which can be used later on to
	 * determine completion of the insertion.
	 * 
	 * @param key
	 *            The {@link Key} with which <code>entry</code> will be
	 *            associated.
	 * @param entry
	 *            The entry to insert.
	 * @return {@link ChordFuture}, which can be used later on to determine
	 *         completion of the insertion.
	 */
	public ChordFuture insertAsync(Key key, Serializable entry);

	/**
	 * Asynchronous method to remove <code>entry</code> with <code>key</code>.
	 * Implementations of this method must return immediately and return an
	 * implementation of {@link ChordFuture}, which can be used later on to
	 * determine completion of the removal.
	 * 
	 * @param key
	 *            The {@link Key} with which <code>entry</code> is associated.
	 * @param entry
	 *            The entry to remove.
	 * @return {@link ChordFuture}, which can be used later on to determine
	 *         completion of the removal.
	 */
	public ChordFuture removeAsync(Key key, Serializable entry);
}
